package com.net.common.util;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 接口使用的线程池
 *
 * @author hjh
 */
public class ThreadPoolFactory {
    /**
     * 核心线程数
     */
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
    /**
     * 最大线程数
     */
    private static final int MAXIMUM_POOL_SIZE = CORE_POOL_SIZE * 10;
    /**
     * 超时时间
     */
    private final static long KEEP_ALIVE_TIME = 60L;


    /**
     * 线程池
     */
    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME,
            // 不能用等待队列线程,池核心数不够没法监听客户端消息
            TimeUnit.SECONDS, new SynchronousQueue<>(), new CustomThreadFactory("net-Thread-"), new ThreadPoolExecutor.DiscardPolicy());


    // 创建一个定时任务线程池
    private static final ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1, new CustomThreadFactory("net-scheduled-task-"));

    /**
     * 执行提交的任务
     *
     * @param runnable 任务
     */
    public static void execute(Runnable runnable) {
        threadPoolExecutor.execute(runnable);
    }

    /**
     * 执行提交的任务带返回值
     *
     * @param callable 任务
     */
    public static <T> Future<T> submit(Callable<T> callable) {
        return threadPoolExecutor.submit(callable);
    }

    /**
     * 设置核心线程数
     *
     * @param corePoolSize 任务
     */
    public static void setCorePoolSize(int corePoolSize) {
        threadPoolExecutor.setCorePoolSize(corePoolSize);
    }

    /**
     * 最大连接数
     *
     * @return int
     */
    public static int getMaxActive() {
        return (MAXIMUM_POOL_SIZE / 2) - CORE_POOL_SIZE;
    }

    public static int getActiveCount() {
        return threadPoolExecutor.getActiveCount();
    }

    public static int getMaximumPoolSize() {
        return threadPoolExecutor.getMaximumPoolSize();
    }

    public static int getCorePoolSize() {
        return threadPoolExecutor.getCorePoolSize();
    }

    public static void shutdown() {
        if (!threadPoolExecutor.isShutdown()) {
            threadPoolExecutor.shutdown();
        }

        if (!scheduledThreadPoolExecutor.isShutdown()) {
            scheduledThreadPoolExecutor.shutdown();
        }
    }

    /**
     * @param runnable
     * @param initialDelay
     * @param period
     * @param unit
     */
    public static void scheduleAtFixedRate(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
        scheduledThreadPoolExecutor.scheduleAtFixedRate(runnable, initialDelay, period, unit);
    }


    /**
     * 线程工厂
     */
    static class CustomThreadFactory implements ThreadFactory {
        private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        private CustomThreadFactory(String namePrefix) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            this.namePrefix = namePrefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }


}


